import { ref, computed, watch } from 'vue'
import type { stepperProps, actionType, currentValueType, rangeType, formateType, setValueType } from './stepper.type'

export const useStepper = (props: stepperProps) => {
  const initValue = props.initValue || props.modelValue

  const formate: formateType = (value) => {
    value = String(value).replace(/[^\d]/g, '')
    return value === '' ? '0' : value
  }

  const range: rangeType = (value) => {
    return Math.max(Math.min(+props.max, +value), +props.min)
  }

  const currentValue = ref<currentValueType>(range(formate(initValue)))

  const handleBtnClick = (type: actionType) =>  {
    if (props.disabled) return
    const diff = type === 'minus' ? -props.step : +props.step
    const value = currentValue.value + diff
    const ranged = range(value)
    setValue(ranged)
  }

  const handleInput = (event: Event) => {
    const input = event.target as HTMLInputElement
    const { value } = input
    const formated = formate(value)
    input.value = formated
    setValue(formated)
  }

  const handleBlur = (event: Event) => {
    const input = event.target as HTMLInputElement
    const { value } = input
    const ranged = range(value)
    input.value = String(ranged)
    setValue(ranged)
  }

  const setValue: setValueType = (value) => {
    currentValue.value = +value
  }

  const resetValue = () => {
    currentValue.value = range(formate(currentValue.value))
  }

  const plusDisabled = computed(() => props.disabled || currentValue.value >= props.max)
  const minusDisabled = computed(() => props.disabled || currentValue.value <= props.min)

  watch(
    [
      () => props.max,
      () => props.min,
      () => props.step,
    ], 
      resetValue
    )

  return {
    currentValue,
    handleBtnClick,
    handleInput,
    handleBlur,
    minusDisabled,
    plusDisabled
  }
}